
#include "SDL.h"

#define GL_API_CALL
#define GL_FRAGMENT_SHADER 0x8B30

typedef unsigned int GLenum;
typedef int GLint;
typedef int GLsizei;
typedef unsigned int GLuint;
typedef char GLchar;
typedef float GLfloat;

typedef GLuint (GL_API_CALL *glCreateShaderProgramv_fn) (GLenum type, GLsizei count, const GLchar **strings);
typedef void (GL_API_CALL *glUseProgram_fn) (GLuint program);
typedef void (GL_API_CALL *glGetProgramInfoLog_fn) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (GL_API_CALL *glTexCoord1f_fn) (GLfloat s);
typedef void (GL_API_CALL *glRecti_fn) (GLint x1, GLint y1, GLint x2, GLint y2);

const GLchar *g_src_fs =
    "float t;"
    "void main(){"
        "t=gl_TexCoord[0].s*.001;"
        "gl_FragColor=vec4(.5+.5*sin(t));"
    "}";

glCreateShaderProgramv_fn glCreateShaderProgramv;
glUseProgram_fn glUseProgram;
glGetProgramInfoLog_fn glGetProgramInfoLog;
glTexCoord1f_fn glTexCoord1f;
glRecti_fn glRecti;

static void audio_callback(void *userdata, Uint8 *stream, int len) {
    static int sample = 0;
    static float freq = 220.0f;
    int i;
    for (i = 0; i < len / 2; ++i) {
        float t = sample++ / 44100.0f;
        float y = sinf(2 * 3.1415926f * freq * t);
        ((short *)stream)[i] = (short)(y * 32767.0);
    }
}

int main() {
    SDL_Event evt;
    SDL_AudioSpec audio_spec = { 44100, AUDIO_S16, 1, 0, 2048, 0, 0, audio_callback, NULL };

    SDL_SetVideoMode(1280, 720, 0, SDL_OPENGL | SDL_NOFRAME);

    glCreateShaderProgramv = (glCreateShaderProgramv_fn) SDL_GL_GetProcAddress("glCreateShaderProgramv");
    glUseProgram = (glUseProgram_fn) SDL_GL_GetProcAddress("glUseProgram");
    glGetProgramInfoLog = (glGetProgramInfoLog_fn) SDL_GL_GetProcAddress("glGetProgramInfoLog");
    glTexCoord1f = (glTexCoord1f_fn) SDL_GL_GetProcAddress("glTexCoord1f");
    glRecti = (glRecti_fn) SDL_GL_GetProcAddress("glRecti");

    glUseProgram(glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &g_src_fs));

    SDL_OpenAudio(&audio_spec, NULL);
    SDL_PauseAudio(0);

    while (1) {
        glTexCoord1f((float) SDL_GetTicks());
        glRecti(-1, -1, 1, 1);
        SDL_GL_SwapBuffers();

        SDL_PollEvent(&evt);
        if (evt.type == SDL_KEYDOWN) break;
    }

    SDL_CloseAudio();
    SDL_Quit();

    return 0;
}
